﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Microsoft.SharePoint;
using System.Diagnostics;

namespace SharePointOfView.ExtensionMethods
{
    public static class BaseCollection
    {
        private static Dictionary<Type, MethodInfo> dicMethodInfos = new Dictionary<Type, MethodInfo>();

        /// <summary>
        /// Try to get the object stored in the SPBaseCollection.
        /// </summary>
        /// <typeparam name="T">SPList, SPUser, SPWeb, etc... anything inheriting from SPBaseCollection</typeparam>
        /// <param name="baseCollection">The SPBaseCollection (SPListsCollection, SPUsers, SPWebs, etc ...) where we will search</param>
        /// <param name="name">The index of the object we are looking for (name, login, etc...)</param>
        /// <param name="result">The expected object</param>
        /// <returns>
        /// Return a True of False depending on the operations success, and places the result into the result passed in
        /// </returns>
        public static bool SovTryGet<T>(this SPBaseCollection baseCollection, string name, out T result)
        {
            result = default(T);
            Type typeCollection = null;
            try
            {
                MethodInfo methodInfo = null;
                typeCollection = baseCollection.GetType();

                if (dicMethodInfos.ContainsKey(typeCollection) == false)
                {
                    methodInfo = typeCollection.GetMethod("get_Item",
                                     BindingFlags.InvokeMethod | BindingFlags.ExactBinding | BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly,
                                     null,
                                     new Type[] { typeof(string) },
                                     null);
                    dicMethodInfos.Add(typeCollection, methodInfo);
                }
                else
                    methodInfo = dicMethodInfos[typeCollection];

                if (methodInfo == null)
                    return false;

                result = (T)methodInfo.Invoke(baseCollection, new object[] { name });
                return true;
            }
            catch (Exception ex)
            {
                Trace.Write(String.Format("SharePointOfView.ExtensionMethods > {0} : {1}", "TryGet", ex.InnerException.Message), "Monitorable");
                return false;
            }
        }
    }
}
